package
{
	import flash.display.Bitmap;
	import flash.display.BitmapData;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.events.MouseEvent;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	import flash.utils.Dictionary;
	import flash.utils.getTimer;
	
	[SWF(width=480, height=320, frameRate=24, backgroundColor=0xE2E2E2)]
	public class ActionScriptBlittingPart4 extends Sprite
	{
		
		public function ActionScriptBlittingPart4()
		{
			init();
			stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
			stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
		}
		
		[Embed(source="spritesheets/greengel.png")]
		public var GreenGel:Class;
		
		[Embed(source="spritesheets/greengelmelt.png")]
		public var GreenGelMelt:Class;
		
		[Embed(source="spritesheets/browncollector.png")]
		public var BrownCollector:Class;
		
		public var canvas:BitmapData;
		public var canvasClearRect:Rectangle;
		public var spritesheetCollector:BitmapData;
		public var spritesheetGel:BitmapData;
		public var spritesheetGelMelt:BitmapData;
		public var rect:Rectangle;
		private var currentTile:int = 0;
		
		// ** Gel Variables ** //
		private var gels:Dictionary = new Dictionary(true);
		private var gelCount:int = 0;
		
		// ** Collector's Position ** //
		private var collectorX:int = 20;
		private var collectorY:int = 30;
		private var destX:int = 160;
		private var destY:int = 280;
		
		private var tickPosition:int = 0;
		private var tickLastPosition:int = -1;
		private var framePeriod:int = 66;//33; // 1000 / 20 - (1 sec / frame rate)
		
		/**
		 * 	Initialize method
		 */
		private function init():void
		{
			// Set our game timer to the stage frameRate
			framePeriod = int(1000 / stage.frameRate);
			
			// Create input bitmap instance
			spritesheetGel = (new GreenGel() as Bitmap).bitmapData;
			// Create input bitmap instance
			spritesheetGelMelt = (new GreenGelMelt() as Bitmap).bitmapData;
			// Create input bitmap instance
			spritesheetCollector = (new BrownCollector() as Bitmap).bitmapData;
			
			// Add a Bitmap to the display list that will copyPixels() to.
			canvas = new BitmapData(480, 320, true, 0xFFFFFF);
			addChild(new Bitmap(canvas));
			
			canvasClearRect = new Rectangle(0, 0, 480, 320);
			// Tile Size
			rect = new Rectangle(0, 0, 40, 40);
		}
		
		/**
		 * 	Handles the timer
		 */
		private function enterFrameHandler(event:Event):void
		{
			var time:uint = getTimer();
			tickPosition = int((time % 1000) / framePeriod);
			
			if (tickLastPosition != tickPosition)
			{
				tickLastPosition = tickPosition;
				canvas.lock();
				canvas.fillRect(canvasClearRect, 0x000000);
				render();
				canvas.unlock();
			}
			
			// Randomly Add Gels
			if (time % 157 < 3)
				createGel();
		}
		
		/**
		 * 	Render any bitmap data.
		 */
		private function render():void
		{
			rect.x = (currentTile % 5) * 40;
			rect.y = int(currentTile / 5) * 40;
			collectorX += (destX-collectorX-20)/5;
			collectorY += (destY-collectorY-30)/5;
			canvas.copyPixels(spritesheetCollector, rect, 
				new Point(collectorX, collectorY), null, null, true);
			// Render Gel at half the frame rate, to slow it down
			if (currentTile % 2 == 1)
			{
				rect.x = ((currentTile-1) % 5) * 40;
				rect.y = int((currentTile-1) / 5) * 40;
			}
			for each (var gel:Object in gels)
			{
				// Hit Check 5 px within Y and X
				if (Math.abs(gel.posY - collectorY + 6) < 14
					&& Math.abs(gel.posX - collectorX) < 10)
				{
					gel.state = "melt";
				}
				if (gel.state == "melt")
				{
					// Clear out if done metling
					if (gel.meltFrame < 20)
						gel.meltFrame++;
					else
					{
						delete gels[gel.name];
						continue;
					}
					rect.x = (gel.meltFrame % 5) * 40;
					rect.y = int(gel.meltFrame / 5) * 40;
					canvas.copyPixels(spritesheetGelMelt, rect, 
						new Point(collectorX-1, collectorY-12), null, null, true);
					continue;
				}
				else
				{
					canvas.copyPixels(spritesheetGel, rect, 
						new Point(gel.posX, gel.posY), null, null, true);
				}
				
				gel.posY += 3;
				if (gel.posY > 320)
				{
					delete gels[gel.name];
					continue;
				}
					
			}
			
			currentTile = ++currentTile % 20;
		}
		
		/**
		 * 	Used to move the animation around.
		 */
		private function mouseUpHandler(event:MouseEvent):void
		{
			destX = event.stageX;
			destY = event.stageY;
		}
		
		/**
		 * 	Create a gel
		 */
		private function createGel():void
		{
			var gel:Object = new Object();
			gel.posX = ((Math.random() * 0xffffff) % 280) + 20
			gel.posY = 0;
			gel.state = "animate";
			gel.meltFrame = 0;
			gel.name = "gel" + gelCount++;
			gels[gel.name] = gel;
		}
	}
}